﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace XUtility
{
    #region 方法 扩展方法
    /// <summary>
    /// 
    /// </summary>
    public static class MethodEx
    {
        #region 调用方法
        /// <summary>
        /// 调用方法
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="instance">类 一般为 this</param>
        /// <param name="name">方法名称</param> 
        /// <param name="param">参数</param>
        /// <returns></returns>
        public static void CallMethod(this Object instance, String name, params Object[] param)
        {
            if (instance != null && name.HasValue())
            {
                Type type = instance.GetType();
                MethodInfo method = type.GetMethod(name);
                method.Invoke(instance, param);
            }
        }

        /// <summary>
        /// 调用方法
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="instance">类 一般为 this</param>
        /// <param name="name">方法名称</param>
        /// <param name="param">参数</param>
        /// <returns>返回值</returns>
        public static T CallMethod<T>(this Object instance, String name, Object param)
        {
            return CallMethod<T>(instance, name, new Object[] { param });
        }

        /// <summary>
        /// 调用方法
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="instance">类 一般为 this</param>
        /// <param name="name">方法名称</param> 
        /// <param name="param">参数</param>
        /// <returns>返回值</returns>
        public static T CallMethod<T>(this Object instance, String name, params Object[] param)
        {
            if (instance != null && name.HasValue())
            {
                Type type = instance.GetType();
                MethodInfo method = type.GetMethod(name);
                return (T)method.Invoke(instance, param);
            }
            return default(T);
        }
        #endregion

        #region 调用私有方法
        /// <summary>
        /// 调用私有方法
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="instance">类 一般为 this</param>
        /// <param name="name">方法名称</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public static void CallPrivateMethod(this Object instance, String name, params Object[] param)
        {
            if (instance != null && name.HasValue())
            {
                BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
                Type type = instance.GetType();
                MethodInfo method = type.GetMethod(name, flag);
                method.Invoke(instance, param);
            }
        }

        /// <summary>
        /// 调用私有方法
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="instance">类 一般为 this</param>
        /// <param name="name">方法名称</param>
        /// <param name="param">参数</param>
        /// <returns>返回值</returns>
        public static T CallPrivateMethod<T>(this Object instance, String name, Object param)
        {
            return CallPrivateMethod<T>(instance, name, new Object[] { param });
        }

        /// <summary>
        /// 调用私有方法
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="instance">类 一般为 this</param>
        /// <param name="name">方法名称</param>
        /// <param name="param">参数</param>
        /// <returns>返回值</returns>
        public static T CallPrivateMethod<T>(this Object instance, String name, params Object[] param)
        {
            if (instance != null && name.HasValue())
            {
                BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
                Type type = instance.GetType();
                MethodInfo method = type.GetMethod(name, flag);
                return (T)method.Invoke(instance, param);
            }
            return default(T); 
        }
        #endregion
    }
    #endregion
}
